<script setup>
import { computed, ref } from 'vue'
import FormRadioItem from './FormRadioItem.vue'
import FormCheckboxItem from './FormCheckboxItem.vue'
import FormSelectItem from './FormSelectItem.vue'
import FormInputItem from './FormInputItem.vue'
import FormAutocompleteItem from './FormAutocompleteItem.vue'
import FormSwitchItem from './FormSwitchItem.vue'
import FormDateItem from './FormDateItem.vue'
import FormSlotItem from './FormSlotItem.vue'
const props = defineProps({
  columns: {
    type: Array,
    required: true,
    validator: (value) => Array.isArray(value)
  },
  model: {
    type: Object,
    default: () => ({})
  },
  options: {
    type: Object,
    default: () => ({})
  },
  // 新增 grid 相关配置
  grid: {
    type: Object,
    default: () => ({
      cols: 1, // 默认一行一列
      gap: 20, // 默认间距
    })
  }
})

const emit = defineEmits(['submit', 'reset', 'cancel'])

const formModel = ref({})
const formRef = ref()

const _options = computed(() => ({
  labelPosition: 'right',
  disabled: false,
  submitButtonText: '提交',
  resetButtonText: '重置',
  cancelButtonText: '取消',
  showResetButton: true,
  ...props.options
}))

// 计算栅格样式
const gridStyle = computed(() => {
  const { cols = 1, gap = 20 } = props.grid
  return {
    display: 'grid',
    gridTemplateColumns: `repeat(${cols}, 1fr)`,
    gap: `${gap}px`,
  }
})

const initFormModel = (columns, model) => {
  return columns.reduce((acc, item) => {
    acc[item.field] = model?.[item.field] ?? (item.type === 'checkbox' ? [] : '')
    return acc
  }, {})
}

watch(
    () => props.model,
    () => {
      formModel.value = initFormModel(props.columns, props.model)
    },
    { immediate: true }
)

const getFormItem = (type) => {
  const map = {
    radio: FormRadioItem,
    checkbox: FormCheckboxItem,
    select: FormSelectItem,
    input: FormInputItem,
    autocomplete: FormAutocompleteItem,
    switch: FormSwitchItem,
    date: FormDateItem,
    daterange: FormDateItem,
    slot: FormSlotItem
  }
  return map[type] || FormInputItem
}

const onSubmit = async (formEl) => {
  if (!formEl) return

  try {
    await formEl.validate()
    emit('submit', formModel.value)
  } catch (error) {
    console.error('表单验证失败:', error)
  }
}

const handleKeyUp = (enterable) => {
  if (!enterable) return
  onSubmit(formRef.value)
}

const resetForm = (formEl) => {
  if (!formEl) return
  formEl.resetFields()
  emit('reset')
}

defineExpose({
  formRef
})
</script>

<template>
  <el-form v-bind="_options" ref="formRef" :model="formModel" @submit.prevent>
    <!-- 新增栅格容器 -->
    <div :style="gridStyle">
      <template v-for="(item, index) in columns" :key="index">
        <!-- 支持单独设置某个表单项占据的列数 -->
        <div :style="{ gridColumn: item.span ? `span ${item.span}` : 'span 1' }">
          <component
              :is="getFormItem(item.type)"
              v-model="formModel[item.field]"
              v-bind="item"
              @keyup-enter="handleKeyUp(item.enterable)"
          >
            <template v-if="item.type === 'slot'" #[item.slotName]="slotProps">
              <slot
                  :name="item.slotName"
                  :value="formModel[item.field]"
                  :update-value="(val) => formModel[item.field] = val"
              />
            </template>
          </component>
        </div>
      </template>
    </div>

    <el-form-item>
      <slot name="buttons" :model="formModel" :form-ref="formRef">
        <el-button type="primary" @click="onSubmit(formRef)">
          {{ _options.submitButtonText }}
        </el-button>
        <el-button v-if="_options.showResetButton" @click="resetForm(formRef)">
          {{ _options.resetButtonText }}
        </el-button>
        <el-button v-if="_options.showCancelButton" @click="emit('cancel')">
          {{ _options.cancelButtonText }}
        </el-button>
      </slot>
    </el-form-item>
  </el-form>
</template>
